import { EventTarget } from "cc";

/**
 * 事件管理
 */
export const eventMgr = _ as EventMgr;
export class EventMgr {

    et: EventTarget;

    init() {
        (eventMgr as any) = this;
        this.et = new EventTarget();
    }

    /**
     * 监听事件
     * @param id 
     * @param callback 
     * @param caller 
     */
    on<EventId extends keyof EventData>(id: EventId, callback: (data?: EventData[EventId]) => any, caller?: any): void
    on(id: Exclude<EventId, keyof EventData>, callback: () => any, caller?: any): void
    on(id: EventId, callback: (data?: any) => any, caller?: any) {
        this.et.on(id, callback, caller);
    }

    /**
     * 监听事件 触发一次后取消监听
     * @param id 
     * @param callback 
     * @param caller 
     */
    once<EventId extends keyof EventData>(id: EventId, callback: (data?: EventData[EventId]) => any, caller?: any): void
    once(id: Exclude<EventId, keyof EventData>, callback: () => any, caller?: any): void
    once(id: EventId, callback: (data?: any) => any, caller?: any) {
        this.et.on(id, callback, caller, true);
    }

    /**
     * 取消监听事件
     * @param id 
     * @param callback 
     * @param caller 
     */
    off(id: EventId, callback: (data?: any) => any, caller?: any) {
        this.et.off(id, callback, caller);
    }

    /**
     * 发送事件
     * @param id 
     * @param data 
     */
    send<EventId extends keyof EventData>(id: EventId, data: EventData[EventId]): void
    send(id: Exclude<EventId, keyof EventData>): void
    send(id: EventId, data?: any): void {
        this.et.emit(id, data);
    }

}

/**
 * 事件ID
 */
export enum EventId {

    // === LoadMgr
    /** 表格重载 */
    reloadXlsx,

    // === ConnMgr
    /** Gate连接结果 */
    gateConn,
    /** Gate断开连接 */
    gateDisconn,
    /** 服务器连接结果 */
    svrConn,
    /** 服务器断开连接 */
    svrDisConn,

    // === PopupMgr
    /** 飘字 */
    floatText,

    // === BaseView
    /** 界面打开 */
    viewOpen,
    /** 界面关闭 */
    viewClose,

    // === Loading
    /** 加载内容 */
    loadingStr,
    /** 加载进度 */
    loadingProg,

}


declare global {
    /** 事件携带数据 */
    interface EventData { }
}